package com.dnndo.system.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dnndo.common.constant.RoleConstants;
import com.dnndo.common.core.domain.entity.SysRole;
import com.dnndo.common.utils.DateUtils;
import com.dnndo.common.utils.SecurityUtils;
import com.dnndo.common.utils.bean.BeanDtoVoUtil;
import com.dnndo.system.domain.Menu;
import com.dnndo.system.domain.dto.MenuInsertDTO;
import com.dnndo.system.domain.dto.MenuUpdateDTO;
import com.dnndo.system.domain.vo.MenuMetaAuths;
import com.dnndo.system.mapper.MenuMapper;
import com.dnndo.system.service.IMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 菜单Service业务层处理
 * 
 * @author dnndo
 * @date 2025-04-23
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService
{
    @Autowired
    private MenuMapper menuMapper;

    /**
     * 查询菜单
     * 
     * @param id 菜单主键
     * @return 菜单
     */
    @Override
    @DS("public")
    public Menu selectMenuById(Long id)
    {
        return menuMapper.selectById(id);
    }

    /**
     * 新增菜单
     *
     * @return 结果
     */
    @Override
    @DS("public")
    public int insertMenu(MenuInsertDTO dto)
    {
        Menu menu = BeanDtoVoUtil.convert(dto, Menu.class);
        menu.setParentId(dto.getParentId() == null || dto.getParentId() == 0L ? 0L : dto.getParentId());
        menu.setCreateTime(DateUtils.getNowDate());
        menu.setUpdateTime(DateUtils.getNowDate());
        menu.setCreateBy(SecurityUtils.getUserId().toString());
        menu.setUpdateBy(SecurityUtils.getUserId().toString());
        menu.setDelFlag(0L);
        return menuMapper.insert(menu);
    }

    /**
     * 修改菜单
     * @return 结果
     */
    @Override
    @DS("public")
    public int updateMenu(MenuUpdateDTO dto)
    {
        Menu menu = BeanDtoVoUtil.convert(dto, Menu.class);
        menu.setParentId(dto.getParentId() == null || dto.getParentId() == 0L ? 0L : dto.getParentId());
        menu.setUpdateTime(DateUtils.getNowDate());
        menu.setUpdateBy(SecurityUtils.getUserId().toString());
        return menuMapper.updateById(menu);
    }

    /**
     * 删除菜单信息
     * 
     * @param id 菜单主键
     * @return 结果
     */
    @Override
    public int deleteMenuById(Long id)
    {
        return menuMapper.deleteMenuById(id);
    }

    @Override
    @DS("public")
    public List<Tree<Long>> getTree() {
        //查询所有菜单
        List<Menu> menus = menuMapper.selectList(null);
        return getTrees(menus);
    }

    /**
     * 获取菜单树
     */
    private static List<Tree<Long>> getTrees(List<Menu> menus) {
        MenuParserImpl menuParser = new MenuParserImpl();
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setIdKey("id");
        treeNodeConfig.setNameKey("name");
        treeNodeConfig.setChildrenKey("children");
        treeNodeConfig.setParentIdKey("parentId");
        return TreeUtil.build(menus, 0L, treeNodeConfig, menuParser);
    }

    @Override
    @DS("public")
    public Set<String> getPermsByRole(SysRole role) {
        //初始化是否是超级管理员
        boolean isSuperAdmin = role.getRoleType().equals(RoleConstants.ROLE_TYPE_SUPER_ADMIN);
        //初始化权限集合
        Set<String> perms = new HashSet<>();
        //如果是超级管理员就全部菜单
        if (isSuperAdmin) {
            List<Menu> menus = menuMapper.selectList(null);
            // 如果菜单不为空就循环菜单获取权限
            if (!menus.isEmpty()) {
                for (Menu menu : menus) {
                    //将menu.getMeta().getAuths()中的value取出转成list
                    List<String> menuIds = List.of();
                    if (menu.getMeta().getAuths() != null && !menu.getMeta().getAuths().isEmpty()) {
                         menuIds = menu.getMeta().getAuths().stream()
                                .map(MenuMetaAuths::getValue)
                                .toList();
                    }
                    //将menuIds中的值添加到perms中
                    if (!menuIds.isEmpty()) {
                        perms.addAll(menuIds);
                    }
                }
            }
        } else
        // 如果是管理员则从角色中取出菜单
        {
            if (role.getAuths() != null && !role.getAuths().isEmpty()) {
                perms.addAll(role.getAuths());
            }
        }
        return perms;
    }
}
